package social.server.main;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.util.Iterator;
import java.util.List;

public class Location {

	String userLogin;
	double lat;
	double lng;
	double distanceToFriend;
	static List<User> friendsDistance;

	/**
	 * construtor da classe
	 * 
	 * @param lat
	 *            latitude
	 * @param lgn
	 *            longitude
	 */
	public Location(Double lat, Double lgn, String userLogin) {
		this.lat = lat;
		this.lng = lgn;
		this.userLogin = userLogin;
	}

	/**
	 * 
	 * @return lat
	 */
	public Double getLat() {
		return this.lat;
	}

	/**
	 * 
	 * @return longitude
	 */
	public Double getLng() {
		return this.lng;
	}

	/**
	 * 
	 * @param endereco
	 * @return url das coordenadas do individuo
	 */
	public static String addressURL(String endereco) {

		String address = endereco.replace(" ", "+");
		String url = "http://maps.google.com/maps/api/geocode/xml?address="
				+ address + "&sensor=true";
		return url;
	}

	/**
	 * 
	 * @param endereco
	 * @return um tipo Location com as coordenadas do individuo
	 */
	public static Location sayLocation(String endereco, String userLogin) {
		DecimalFormat dff = (DecimalFormat) DecimalFormat.getInstance();
		Double lat2 = null;
		Double lgn2 = null;

		try {
			URL url = new URL(endereco);
			BufferedReader in = new BufferedReader(new InputStreamReader(
					url.openStream()));
			String str;
			String lat = "";
			String lgn = "";
			while ((str = in.readLine()) != null) {
				if (str.endsWith("</lat>")) {
					lat = str.trim();
				}
				if (str.endsWith("</lng>")) {
					lgn = str.trim();
				}

			}

			lat = lat.replace("</lat>", "");
			lat = lat.replace("<lat>", "");
			lat = lat.replace(".", ",");

			lgn = lgn.replace("</lng>", "");
			lgn = lgn.replace("<lng>", "");
			lgn = lgn.replace(".", ",");

			try {
				lat2 = (Double) dff.parse(lat);
				lgn2 = (Double) dff.parse(lgn);
			} catch (ParseException e) {
				e.printStackTrace();
			}

			in.close();

		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		Location local = new Location(lat2, lgn2, userLogin);

		return local;

	}

	/**
	 * 
	 * @param local1
	 * @param local2
	 * @return a distancia entre duas pessoas
	 */
	public static Double calculaDistancia(Location local1, Location local2) {
		return Math.sqrt(Math.pow((local1.getLat() - local2.getLat()), 2)
				+ Math.pow((local1.getLng() - local2.getLng()), 2));
	}

	public void calculateFriendsDistance() throws Exception {
		List<String> friendList = System.getInstance().getUser(userLogin)
				.getFriendList();
		User user;
		Iterator<String> it = friendList.iterator();

		while (it.hasNext()) {
			user = System.getInstance().getUser(it.next());
			user.setDistanceToFriend(calculaDistancia(this, user.getPosition()));
			friendsDistance.add(user);
		}
	}

	/**
	 * ordena os usuarios a partir da posiciao de um usuario
	 * 
	 * @param user
	 *            usuario em q a lista sera gerada a partir dele
	 * @return
	 * @throws Exception
	 */
	public static User[] orderByPosition(User user) throws Exception {

		List<String> l1 = user.getFriendList();
		User[] list = new User[l1.size()];

		Iterator<String> it = l1.iterator();

		for (int i = 0; i < l1.size(); i++) {
			list[i] = System.getInstance().getUser(it.next());
		}

		for (int i = 0; i < list.length; i++) {
			for (int j = 0; j < list.length; j++) {
				if (calculaDistancia(user.getPosition(), list[i].getPosition()) < calculaDistancia(
						user.getPosition(), list[j].getPosition())) {
					swap(list, i, j);
				}
			}

		}
		return list;
	}

	public void orderByPosition() throws Exception {

		Iterator<User> it = friendsDistance.iterator();

		// Implementar bubble sort na lista friendsDistance;

	}

	public static void swap(User[] list, int i, int j) {
		User temp = list[i];
		list[i] = list[j];
		list[j] = temp;
	}

}
